#pragma once
#include <DirectXMath.h>
#include <iostream>

namespace mray{

enum AXIS : unsigned char{X, Y, Z, NUM,};

struct vec3{

	vec3();
	vec3(float x, float y, float z, float a = 0.f);

	float& operator [](int i){ return data[i]; }
	const float& operator [](int i)const{return data[i];}

	vec3 operator + (const vec3& v)const;
	vec3 operator - (const vec3& v)const;
	vec3 operator * (float f)const;
	vec3 operator / (float f)const;

	vec3 operator - (void)const;

	vec3& operator += (const vec3& v);
	vec3& operator -= (const vec3& v);
	vec3& operator *= (float f);
	vec3& operator /= (float f);

	//shade
	vec3 operator ^(const vec3& v)const;
	vec3& operator ^= (const vec3& v);

	float operator * (const vec3& v)const;
	vec3 operator %(const vec3& v)const;
	float length()const;
	float dbl_length()const;
	float LengthAndNorm();
	AXIS GetMaxAbsAxis()const;
	AXIS GetMinAbsAxis()const;
	AXIS GetMaxAxis()const;
	AXIS GetMinAxis()const;
	float GetXYZ()const;
	//normailize self
	vec3& normalize(void);

	union{
		struct {float x, y, z, a;};
		struct {float r, g, b, a;};
		struct {float u, v, w, a;};
		float data[4];
		DirectX::XMVECTOR xmvec;
	};

	friend std::ostream& operator << (std::ostream& os, const mray::vec3& v);
};

}

